package com.example.sentinel.controller;

import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Created with IntelliJ IDEA 2023.
 * Description:
 * User: 故我
 * Date: 2024-02-15
 * Time: 13:20
 */
@RestController
@RequestMapping("/user")
public class UserController {

    /**
     * 通过代码 SphU代码的方式定义资源
     */
    @RequestMapping("/getname")
    public String getName() throws InterruptedException {
        try (Entry entry = SphU.entry("getname")) {  // 与请求路径名一致
            Thread.sleep(100);
            return "-- getUser --";
        } catch (BlockException e) {
            // 这里是被限流之后执行
            // 根据异常进行判断是否是限流 还是熔断
            if (e instanceof DegradeException) {
                return "SphU 被熔断了！";
            } else if (e instanceof FlowException) {
                return "SphU 被限流了！";
            }
            return "SphU 被限制了！";
        }
    }

    /**
     * 通过注解的方式，定义资源 + 限流后执行的方法
     */
    @SentinelResource(value = "getid",
            blockHandler = "myBlockHander")
    @RequestMapping("/getid")
    public String getId(Integer id) throws InterruptedException {
        Thread.sleep(100);
        return "ID: " + id;
    }

    /**
     * 被限流之后要执行的方法
     * 参数 + 返回值 都要相同  + BlockException 异常
     */
    public String myBlockHander(Integer id, BlockException exception) {
        return " Resource 被限制了！";
    }

}
